# -*- coding: utf-8 -*-
import time

from scapy.all import *
import threading

from PyQt5.QtCore import QThread, pyqtSignal
from PyQt5.QtGui import QTextCursor
from Flask_app import app_run

from scapy_sniff import *

import sys
import matplotlib
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QApplication, QDialog

matplotlib.use('Qt5Agg')

from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg
from matplotlib.figure import Figure


from socket import *
import multiprocessing  #多进程
from DataBase_redis import *
import DataBase_online_MYSQL

from GUI_from_qtdesigner import Ui_spoolingui


#参数区
#*********************************************************************************
xmax = 240  # X坐标轴,决定了共有多少个点
ymin = 0
ymax = 500  # Y坐标轴上限
elapsedTime = 100  # 绘图刷新间隔时间delaytime

flaskPort=5000 #flask网页框架端口号

#****************************************************************************

#创建进程：改为在点击按钮后再创建
# p5 = multiprocessing.Process(target=db_clear)

# 使用socket作为进程间通信的方式
HOST = '127.0.0.1'
PORT = 9998  # 服务端端口号
ADDR = (HOST, PORT)
BUFFSIZE = 1024  # 数据的缓存区大小
def log_Threading(textBrowser_2):
    filename=time.strftime("%Y-%m-%d %H_%M_%S", time.localtime())
    textBrowser_2.append("数据帧转码日志正在保存...")
    with open(r"log\fpga_" + filename + ".log", "a+") as f:
        f.write("\n")  # 自带文件关闭功能，不需要再写f.close()
    while not r.llen('msg')==0:
        content=r.blpop('msg',60)
        # time.sleep(100)
        if not content:
            continue
        with open(r"log\fpga_"+filename+".log", "a+") as f:
            f.write(content[1])  # 自带文件关闭功能，不需要再写f.close()
    textBrowser_2.append("数据帧解析日志保存成功！文件名：" + filename + ".log")
        # textBrowser_2.append(content[1])
        # textBrowser_2.moveCursor(textBrowser_2.textCursor().End)
        # udpSocket = socket(AF_INET, SOCK_DGRAM)
        # udpSocket.bind(ADDR)
        # content, destInfo = udpSocket.recvfrom(BUFFSIZE)
        # #这里输出的内容会显示在GUI窗口
        # textBrowser_2.append(content.decode("utf-8"))
        # textBrowser_2.moveCursor(textBrowser_2.textCursor().End)

def redis_to_mysql_Threading(textBrowser_2):
    textBrowser_2.append("redis数据正在上传云端...")
    fpga = r.lrange("fpga", 0, -1)
    for i in fpga:
        data=i.split("_")
        DataBase_online_MYSQL.insert_MYSQL_DB(data[0], data[1], data[2])
    # while not r.llen('mysql')==0:
    #     content=r.blpop('mysql',60)
    #     # time.sleep(100)
    #     if not content:
    #         continue
    #     data=content[1].split("_")
    #     DB_MYSQL.insert_MYSQL_DB(data[0], data[1], data[2])
    textBrowser_2.append("redis内存数据已全部上传云数据库！")

# def kernel():
#     pass

#matplotlib绘图数据list
listx = []
listy = []

class mydialog(QDialog, Ui_spoolingui):
    def __init__(self, parent=None):
        super(mydialog, self).__init__(parent)
        self.setupUi(self)

        self.l = QtWidgets.QVBoxLayout(self.widget)  # 绘图布局
        self.dc = MyMplCanvas(self.widget, width=5, height=4, dpi=100)
        # self.dc.update_figure()
        self.l.addWidget(self.dc)

        # self.th = MyThread()
        # self.th.signalForText.connect(self.onUpdateText)
        # sys.stdout = self.th  # 把print()重定向到线程

        # 开启监听服务进行进程间通信，gui输出


        self.show_adapter.clicked.connect(self.adapter_out)
        self.db_clear.clicked.connect(self.db_clr)
        self.log_save_button.clicked.connect(self.log_save_threading)
        self.sniff_on.clicked.connect(self.sniff)

        self.start_matplotlib.clicked.connect(self.startMatplotlib)
        self.flask_on.clicked.connect(self.flask)
        self.open_url.clicked.connect(self.explor)
        self.redis_to_mysql.clicked.connect(self.redis_mysql_on)
        self.db_clear_mysql.clicked.connect(self.db_clear2)
        self.open_url_online.clicked.connect(self.explor2)
    # def onUpdateText(self, text):
    #     cursor = self.process.textCursor()
    #     cursor.movePosition(QTextCursor.End)
    #     cursor.insertText(text)
    #     self.process.setTextCursor(cursor)
    #     self.process.ensureCursorVisible()

    def sniff(self):

        global iface_name, file_name, filter_rlues, catch_count
        if self.onlinemode.isChecked():
            iface_name = str(self.adapter_name.text())
            file_name=None
        else:
            iface_name = None
            file_name = str(self.offlinefilename.text())
        filter_rlues=str(self.filter_rules.text())
        catch_count=int(self.catch_count.text())

        global skip_count,hex_start,hex_end,hex_data_count
        skip_count=int(self.skip_count.text())
        hex_start=int(self.hex_start.text())
        hex_end=int(self.hex_end.text())
        hex_data_count=int(self.hex_data_num.text())

        p1 = multiprocessing.Process(target=snifferIface, args=(iface_name,file_name, filter_rlues, catch_count, skip_count, hex_start, hex_end, hex_data_count))
        p1.start()
        self.textBrowser_2.append("正在捕获数据帧...")
        # self.kernelrun()

    def flask(self):
        global flaskPort
        flaskPort=str(self.flask_port.text())
        p4 = multiprocessing.Process(target=app_run, args=(flaskPort,))
        p4.start()
        self.textBrowser_2.append("已开启网站后台，地址：" + "http://" + "127.0.0.1" + ":" + flaskPort + "/")
        self.textBrowser_2.moveCursor(self.textBrowser_2.textCursor().End)
        # p4.join()  # join()方法是让主进程先等待，再继续

    def adapter_out(self):
        self.textBrowser_2.append('本机网卡信息如下：')
        self.textBrowser_2.append(show_interfaces(print_result=False))
        self.textBrowser_2.moveCursor(self.textBrowser_2.textCursor().End)

    def db_clr(self):
        db_redis_clear()
        self.textBrowser_2.append('清空数据库成功！')
        self.textBrowser_2.moveCursor(self.textBrowser_2.textCursor().End)
        # p5.join()
    def log_save_threading(self):
        self.t1 = threading.Thread(target=log_Threading, args=(self.textBrowser_2,))
        self.t1.start()

    def explor(self):
        import webbrowser
        global flaskPort
        flaskPort=str(self.flask_port.text())
        url='http://127.0.0.1:'+flaskPort+'/'
        webbrowser.open(url)
        self.textBrowser_2.append('打开URL：'+url)



    def startMatplotlib(self):

        global xmax,ymin,ymax,elapsedTime
        xmax=int(self.x_max.text())
        ymin=int(self.y_min.text())
        ymax=int(self.y_max.text())
        elapsedTime = int(self.hex_start_5.text())

        listx.clear()
        listy.clear()
        for i in range(0, xmax):  # for循环给listx,listy赋初值
            listx.append(i)
            listy.append(0)

        self.dc.timer.stop()
        self.l.removeWidget(self.dc)
        self.dc=MyDynamicMplCanvas(self.widget, width=5, height=4, dpi=100)

        # self.t2=threading.Thread(target=self.dc.update_figure)

        self.dc.update_figure()#立即更新一次
        self.l.addWidget(self.dc)
        self.textBrowser_2.append("已开启实时绘图")

    def redis_mysql_on(self):
        self.t2 = threading.Thread(target=redis_to_mysql_Threading, args=(self.textBrowser_2,))
        self.t2.start()
    def db_clear2(self):
        DataBase_online_MYSQL.db_clear()
        self.textBrowser_2.append('清空云数据库成功！')
        self.textBrowser_2.moveCursor(self.textBrowser_2.textCursor().End)
    def explor2(self):
        import webbrowser
        global flaskPort
        flaskPort=str(self.flask_port.text())
        url='http://123.57.48.201:50401/chart/show/f4738ef9417bdf969032/'
        webbrowser.open(url)
        self.textBrowser_2.append('打开URL：'+url)
    # def kernelrun(self):
    #     try:
    #         self.t = MyThread()
    #         self.t.start()
    #     except Exception as e:
    #         raise e

class MyMplCanvas(FigureCanvasQTAgg):
    def __init__(self, parent=None, width=5, height=4, dpi=100):
        fig = Figure(figsize=(width, height), dpi=dpi)
        self.axes = fig.add_subplot(111)

        FigureCanvasQTAgg.__init__(self, fig)
        self.setParent(parent)
        FigureCanvasQTAgg.setSizePolicy(self,
                                   QtWidgets.QSizePolicy.Expanding,
                                   QtWidgets.QSizePolicy.Expanding)
        FigureCanvasQTAgg.updateGeometry(self)
        listx.clear()
        listy.clear()
        for i in range(0, xmax):  # for循环给listx,listy赋初值
            listx.append(i)
            listy.append(0)
        self.timer = QtCore.QTimer(self)  # 定时器
        self.timer.timeout.connect(self.update_figure)
        self.timer.start(1000000000)


    def update_figure(self):
        # x = np.array(listx)
        # y = np.array(listy)
        # x_smooth = np.linspace(x.min(), x.max(), 1000) #平滑处理
        # y_smooth = make_interp_spline(x, y)(x_smooth)
        self.axes.cla()  # 清屏
        self.axes.grid(True)
        self.axes.plot(listx, listy, 'g')
        self.axes.set(xlim=[0, xmax], ylim=[ymin, ymax])
        self.draw()


class MyDynamicMplCanvas(MyMplCanvas):
    def __init__(self, *args, **kwargs):
        MyMplCanvas.__init__(self, *args, **kwargs)
        self.timer = QtCore.QTimer(self)  # 定时器
        self.timer.timeout.connect(self.update_figure)
        self.timer.start(elapsedTime)

    def update_figure(self):
        self.yi=float(get_fpga_last_data_from_redis())
        listy.pop(0)  # 移除列表第一个元素
        listy.append(self.yi)  # 末尾添加一个数yi
        # x = np.array(listx)
        # y = np.array(listy)
        # x_smooth = np.linspace(x.min(), x.max(), 1000) #平滑处理
        # y_smooth = make_interp_spline(x, y)(x_smooth)
        self.axes.cla()  # 清屏
        self.axes.grid(True)
        self.axes.plot(listx, listy, 'g')
        self.axes.set(xlim=[0, xmax], ylim=[ymin, ymax])
        self.draw()



# class MyThread(QThread):
#     signalForText = pyqtSignal(str)
#     def __init__(self,data=None, parent=None):
#         super(MyThread, self).__init__(parent)
#         self.data = data

#     def write(self, text):
#         self.signalForText.emit(str(text))  # 发射信号
#     def run(self):
#         kernel()


if __name__ == '__main__':
    multiprocessing.freeze_support()
    app = QApplication(sys.argv)
    myWin = mydialog()
    myWin.show()
    sys.exit(app.exec_())